using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UMC.Data;
using UMC.Net;
using UMC.WorkFlow.Entities;

namespace UMC.WorkFlow.Subassembly
{
    [UIDesign(Name = "数据同步", Explain = "把表单数据用SQL或Http同步")]
    public class DataSync : UMC.WorkFlow.Responder
    {

        [Design(Caption = "数据同步API", Explain = "根据审批事件用POST到HTTP API接口,返回格式请参考API文档")]
        public HttpSetting Http { get; set; }
        protected override void OnRespond(UMC.WorkFlow.InstanceEvent taskEvent)
        {
            if (this.SQL != null && String.IsNullOrEmpty(this.SQL.SqlText) == false)
                taskEvent.OnEndProcess += SQLEndProcess;

            if (this.Http != null && String.IsNullOrEmpty(this.Http.Url) == false)
                taskEvent.OnEndProcess += HttpEndProcess;
        }
        [DesignAttribute(Caption = "数据同步脚本", Explain = "当执行审批执行的SQL")]
        public SqlStatusSetting SQL { get; set; }
        string sonsorShapeId = "ALL";
        [DesignAttribute(Caption = "触发流程结点", ArgumentType = ArgumentType.Shape)]
        public string ShapeId
        {
            get
            {
                return sonsorShapeId;
            }
            set
            {
                sonsorShapeId = value;
            }
        }
        void SQLEndProcess(UMC.WorkFlow.TaskInstance task, UMC.WorkFlow.InstanceEventArgs e)
        {
            if (String.IsNullOrEmpty(sonsorShapeId) == false && String.Equals(sonsorShapeId, "ALL", StringComparison.CurrentCultureIgnoreCase) == false)
            {
                if (e.Shape.Id.StartsWith(sonsorShapeId) == false)
                {
                    return;
                }
                if (task.Shapes.Exists(s => s.Id.StartsWith(sonsorShapeId) && s.Status == ShapeStatus.Activation))
                {
                    return;
                }
            }



            if ((((int)SQL.CommandType) & 512) > 0)
            {
                if (task.Status == TaskStatus.Completed)
                {
                    SubassemblyHelper.ExecuteNonQuery(SQL, e.Runtime.Items);

                }

            }

            var es = Utility.Enum(SQL.CommandType);
            for (int i = 0; i < es.Length; i++)
            {
                if (es[i] == e.CommandType)
                {
                    SubassemblyHelper.ExecuteNonQuery(SQL, e.Runtime.Items);
                    break;

                }
            }
        }
        void HttpEndProcess(UMC.WorkFlow.TaskInstance task, UMC.WorkFlow.InstanceEventArgs e)
        {
            if (String.IsNullOrEmpty(sonsorShapeId) == false && String.Equals(sonsorShapeId, "ALL", StringComparison.CurrentCultureIgnoreCase) == false)
            {
                if (e.Shape.Id.StartsWith(sonsorShapeId) == false)
                {
                    return;
                }
                if (task.Shapes.Exists(s => s.Id.StartsWith(sonsorShapeId) && s.Status == ShapeStatus.Activation))
                {
                    return;
                }
            }
            var item = e.Runtime.Items;

            var SessionId = (ulong)item[TaskRuntime.EVENT_SESSION_ID];

            if ((((int)Http.CommandType) & 512) > 0)
            {
                if (task.Status == TaskStatus.Completed)
                {

                    Do(item, new TaskSync()
                    {
                        CreationTime = DateTime.Now,
                        Id = Utility.NewId(),
                        InstanceId = task.InstanceId,
                        Manger = Http.Manger,
                        URL = Http.Url,
                        ServiceId = e.Shape.Id,
                        ServiceName = this.Text,
                        ShapeId = e.Shape.Id,
                        ShapeName = e.Shape.Text,
                        Status = 0,
                        TaskId = task.TaskId,
                        Times = 0,
                        SessionId = SessionId

                    });

                }

            }

            var es = Utility.Enum(Http.CommandType);
            for (int i = 0; i < es.Length; i++)
            {
                if (es[i] == e.CommandType)
                {
                    Do(item, new TaskSync()
                    {
                        CreationTime = DateTime.Now,
                        Id = Utility.NewId(),
                        InstanceId = task.InstanceId,
                        Manger = Http.Manger,
                        URL = Http.Url,
                        ServiceId = e.Shape.Id,
                        ServiceName = this.Text,
                        ShapeId = e.Shape.Id,
                        ShapeName = e.Shape.Text,
                        Status = 0,
                        TaskId = task.TaskId,
                        Times = 0,
                        SessionId = SessionId

                    });
                    break;

                }
            }
        }

        void Do(IDictionary dictionary, TaskSync sy)
        {
            // var syncEntity = TaskRuntime.Database.ObjectEntity<TaskSync>();
            new System.Threading.Tasks.Task(() =>
            {
                var curl = new StringBuilder();
                // var items = TaskRuntime.Current.Items;
                var enumer = dictionary.GetEnumerator();
                while (enumer.MoveNext())
                {
                    if (curl.Length > 0)
                    {
                        curl.Append('&');
                    }
                    curl.Append(Uri.EscapeDataString(enumer.Key as string));
                    curl.Append('=');
                    curl.Append(Uri.EscapeDataString((enumer.Value as string) ?? ""));

                }
                try
                {


                    var webr = new Uri(sy.URL).WebRequest();
                    webr.ContentType = "application/x-www-form-urlencoded";
                    var data = JSON.Deserialize(webr.Post(curl.ToString()).ReadAsString()) as Hashtable;
                    if (String.Equals(data["success"] as string, "true") == false)
                    {
                        sy.FormData = curl.ToString();// JSON.Serialize(dictionary);
                        sy.Times = 1;
                        HotCache.Put(sy);
                    }
                }
                catch
                {
                    sy.FormData = curl.ToString();
                    sy.Times = 1;
                    HotCache.Put(sy);
                }
            }).Start();
        }

        protected override void WriteProperty(System.IO.TextWriter writer)
        {
            writer.Write(',');
            JSON.Serialize("ShapeId", this.ShapeId, writer);

            if (this.SQL != null)
            {
                writer.Write(',');
                JSON.Serialize("SQL", this.SQL, writer);
            }
            if (this.Http != null)
            {
                writer.Write(',');
                JSON.Serialize("Http", this.Http, writer);
            }

            base.WriteProperty(writer);
        }
        public override Func<object> GetInstance(string prototypeName)
        {
            switch (prototypeName)
            {
                case "SQL":
                    return () => new SqlStatusSetting();
                case "Http":
                    return () => new HttpSetting();
                default:
                    return base.GetInstance(prototypeName);

            }
        }
        public override void Read(string key, object value)
        {
            switch (key)
            {
                case "ShapeId":
                    this.ShapeId = value as string;
                    break;
                case "Http":
                    this.Http = value as HttpSetting;
                    break;
                case "SQL":
                    this.SQL = value as SqlStatusSetting;
                    break;

            }
            base.Read(key, value);
        }
    }
}
